package v1

import (
	"bytes"
	"image/png"
	"io"
	"net/http"
	"net/url"

	"github.com/hay-kot/httpkit/errchain"
	"github.com/sysadminsmedia/homebox/backend/internal/web/adapters"
	"github.com/yeqown/go-qrcode/v2"
	"github.com/yeqown/go-qrcode/writer/standard"

	_ "embed"
)

//go:embed assets/QRIcon.png
var qrcodeLogo []byte

// HandleGenerateQRCode godoc
//
//	@Summary	Create QR Code
//	@Tags		Items
//	@Produce	json
//	@Param		data	query		string	false	"data to be encoded into qrcode"
//	@Param		size	query		int		false	"size of the QR code in pixels (default: 256)"
//	@Success	200		{string}	string	"image/jpeg"
//	@Router		/v1/qrcode [GET]
//	@Security	Bearer
func (ctrl *V1Controller) HandleGenerateQRCode() errchain.HandlerFunc {
	type query struct {
		// 4,296 characters is the maximum length of a QR code
		Data string `schema:"data" validate:"required,max=4296"`
		Size int    `schema:"size" validate:"min=0,max=1024"`
	}

	return func(w http.ResponseWriter, r *http.Request) error {
		q, err := adapters.DecodeQuery[query](r)
		if err != nil {
			return err
		}

		image, err := png.Decode(bytes.NewReader(qrcodeLogo))
		if err != nil {
			return err
		}

		decodedStr, err := url.QueryUnescape(q.Data)
		if err != nil {
			return err
		}

		qrc, err := qrcode.New(decodedStr)
		if err != nil {
			return err
		}

		// Set default size if not provided or too small
		if q.Size < 64 {
			q.Size = 256
		}

		toWriteCloser := struct {
			io.Writer
			io.Closer
		}{
			Writer: w,
			Closer: io.NopCloser(nil),
		}

		qrwriter := standard.NewWithWriter(toWriteCloser,
			standard.WithLogoImage(image),
			standard.WithQRWidth(uint8(q.Size/25)), // Adjust width based on size
		)

		// Return the QR code as a jpeg image
		w.Header().Set("Content-Type", "image/jpeg")
		w.Header().Set("Content-Disposition", "attachment; filename=qrcode.jpg")
		return qrc.Save(qrwriter)
	}
}
